<template>
  <!-- Vue3组件中的模板结构可以没有跟标签，例如：div -->
  <h1>我是Demo组件</h1>
  <span>当前求和为：{{ sum }}</span><br>
  <button @click="add">点我+1</button>
  <button @click="sum--">点我-1</button>
  <hr>
  <span>当前的信息是：{{ msg }}</span><br>
  <button @click="msg+='!!!!!'">感叹连招</button>
  <hr>

  <h1>人员信息：</h1>
  <span>姓名：{{ person.name }}</span><br>
  <span>年龄：{{ person.age }}</span><br>
  <span>薪资：{{ person.job.j1.salary + 'k' }}</span><br>
  <button @click="person.name += '===>'">姓名变幻</button>
  <button @click="person.age += 1">年龄变幻</button>
  <button @click="person.job.j1.salary += 1">薪资变幻</button>
  <br>

</template>

<script>
// 引入ref 函数
import {reactive, ref, watch} from "vue";

export default {
  name: 'DemoPage',
  // vue2使用watch配置项进行监视
  watch: {
    // // 简单写法
    // sum(newValue, oldValue) {
    //   console.log('sum的值变化了', newValue, oldValue);
    // }

    // // 监视的完整写法
    // sum: {
    //   // 立即监听
    //   immediate: true,
    //   deep: true, // 深度监视
    //   // 监视的回调handler
    //   handler(newValue, oldValue) {
    //     console.log('sum的值变化了', newValue, oldValue);
    //   }
    // }
  },
  // setup: function () {
  //
  // }

  // Vue3引入了新的配置项，值是一个函数，setup是所有Composition API（组合API）“ 表演的舞台 ”。
  // 组件中所用到的：数据、方法等等，均要配置在setup中。
  // - setup函数的两种返回值：
  //    - 若返回一个对象，则对象中的属性、方法, 在模板中均可以直接使用。【重点关注！】
  //    - 若返回一个渲染函数：则可以自定义渲染内容。【了解】
  setup() {
    // 【todo 通过 reactive 封装整个对象的方式来实现数据的响应式】
    let sum = ref(0);
    let msg = ref('你好啊');
    let person = reactive({
      name: '张三',
      age: 18,
      job: {
        j1: {
          salary: 20,
        }
      }
    });

    // 方法
    function add() {
      sum.value++;
    }

    // // 情况一：监视ref所定义的一个响应式数据
    // watch(sum, (newValue, oldValue) => {
    //   console.log('sum的值变化了', newValue, oldValue);
    // }, {
    //   immediate: true, // 立即监听
    // })

    // // 情况二：监视ref所定义的多个响应式数据
    // watch([sum, msg], (newValue, oldValue) => {
    //   console.log('sum或者msg变了：', newValue, oldValue);
    // }, {
    //   immediate: true, // 立即监听
    // })

    // // 情况三：监视 reactive 所定义的一个响应式数据的全部属性
    // // 【bug注意1：此处无法正确的获取到oldValue】
    // // 【bug注意2：强制开启了deep深度监视，且配置无效】
    // watch(person, (newValue, oldValue) => {
    //   console.log('人员信息变化了：', newValue, oldValue);
    // }, {
    //   immediate: true, // 立即监视
    //   deep: true, // 深度监视，强制开启，配置无效
    // })

    // 情况四：监视 reactive 所定义的一个响应式数据中的某个属性
    // watch(person.job, (newValue, oldValue) => {
    //   console.log('person变化了：', newValue, oldValue);
    // }, {
    //   deep: false, // 深度监视，如果监视某一个对象属性的话，该深度监视属性是生效的。
    // });

    // // 现在也可以直接通过person.job进行监视了，可以不写成函数的形式了
    // watch(() => person.job, (newValue, oldValue) => {
    //   console.log('person变化了：', newValue, oldValue);
    // }, {
    //   deep: true, // 深度监视，如果监视某一个对象属性的话，该深度监视属性是生效的。
    // });

    // // 情况五：监视 reactive 所定义的一个响应式数据中的某些属性
    // watch([() => person.name, () => person.age], (newValue, oldValue) => {
    //   console.log('person变化了：', newValue, oldValue);
    // }, {
    //   deep: false, // 深度监视，如果监视某一个对象属性的话，该深度监视属性是生效的。
    // });

    // 特殊情况：
    watch(() => person.job, (newValue, oldValue) => {
      console.log('person变化了：', newValue, oldValue);
    }, {
      // 此处由于监视的是 reactive 定义的对象中的某个属性，所以deep 配置有效。
      deep: true, // 深度监视，如果监视某一个对象属性的话，该深度监视属性是生效的。
    });


    // 方式一：返回对象【常用】
    return {
      sum,
      add,
      msg,
      person,
    }
  },
}
</script>

<style>

</style>
